﻿using System.Collections.Generic;

using Vestras.StarCraft2.Luna.Parser;
using Vestras.StarCraft2.Luna.Parser.Ast;

namespace Vestras.StarCraft2.Luna.Validation {
    public sealed class ValidationEntryPoint {
        static IDictionary<System.Type[], ITypeValidator> typeValidators = new Dictionary<System.Type[], ITypeValidator>();

        private static ITypeValidator GetTypeValidatorForTypeArray(System.Type[] type) {
            foreach (KeyValuePair<System.Type[], ITypeValidator> pair in typeValidators) {
                foreach (System.Type pairType in pair.Key) {
                    foreach (System.Type childType in type) {
                        if (pairType == childType) {
                            return pair.Value;
                        }
                    }
                }
            }

            return null;
        }

        private static bool DoesTypeValidatorMappingContainTypeArray(System.Type[] type) {
            return GetTypeValidatorForTypeArray(type) != null;
        }

        public static bool RegisterTypeValidator(ITypeValidator typeValidator) {
            if (DoesTypeValidatorMappingContainTypeArray(typeValidator.Type)) {
                return false;
            }

            typeValidators.Add(typeValidator.Type, typeValidator);
            return true;
        }

        public static ITypeValidator GetTypeValidatorForType(System.Type[] type) {
            return GetTypeValidatorForTypeArray(type);
        }

        public ValidationEntryPoint(IEnumerable<Entity> entities) {
            this.entities = entities;
            GalaxyNativeElementsSimulator.Initialize();
        }

        IEnumerable<Entity> entities;
        public bool StartValidation() {
            bool allValid = true;
            foreach (Entity entity in entities) {
                bool result = RunTypeValidatorForEntity(entity);
                if (!result) {
                    allValid = false;
                }
            }

            return allValid;
        }

        bool RunTypeValidatorForEntity(Entity entity) {
            System.Type[] type = new[] { entity.GetType() };
            if (DoesTypeValidatorMappingContainTypeArray(type)) {
                ITypeValidator typeValidator = GetTypeValidatorForTypeArray(type);
                return typeValidator.Validate(entity);
            }

            System.Console.WriteLine("ITypeValidator not implemented for type " + type.ToString());
            return false;
        }

        static ValidationEntryPoint() {
            TypeValidatorRegisterer.Register();
        }
    }
}
